﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using Microsoft.AspNetCore.Http;

namespace SmartSiteManagementSystem.Utils
{
    /// <summary>
    /// IP工具类
    /// 用于获取内外网IP
    /// 验证IP有效性
    /// 获取IP值,可取地区范围
    /// 获取真实IP及代理IP
    /// </summary>
    public class IPUtils
    {
        /// <summary>
        /// 外网IP标识
        /// </summary>
        public const int W_IP = 1;

        /// <summary>
        /// 局域网IP标识
        /// </summary>
        public const int L_IP = 0;

      

        /// <summary>
        /// 获取IP值
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static long GetIPValue(string ip)
        {
            if (!IsValidateIP(ip))
            {
                return 0;
            }
            string[] ipArr = ip.Split('.');
            long ipValue = 0;
            for (int i = 0; i < ipArr.Length; i++)
            {
                if (i == 0)
                    ipValue += Convert.ToInt64(ipArr[i]) * 255 * 255 * 255;
                if (i == 1)
                    ipValue += Convert.ToInt64(ipArr[i]) * 255 * 255;
                if (i == 2)
                    ipValue += Convert.ToInt64(ipArr[i]) * 255;
                if (i == 3)
                    ipValue += Convert.ToInt64(ipArr[i]);
            }
            return ipValue;
        }
        /// <summary>
        /// 获取当前服务器IP地址
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetLocalIP(int type)
        {
            string LAN_IP = string.Empty;
            string WAN_IP = string.Empty;
            #region 获取IP
            System.Net.IPAddress[] ipAddss = System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName());
            foreach (System.Net.IPAddress ipAdds in ipAddss)
            {
                string ip = ipAdds.ToString();
                if (ip.Length <= 15)
                {

                    if (ip.StartsWith("192.168.") || ip.StartsWith("10.0.0"))
                    {
                        LAN_IP = ip;
                    }
                    else
                    {
                        WAN_IP = ip;
                    }

                }

            }
            if (type == L_IP)
                return LAN_IP == string.Empty ? "" : LAN_IP;
            if (type == W_IP)
                return WAN_IP == string.Empty ? "" : WAN_IP;
            else
                throw new Exception("Param is ERROR!");
            return "";
            #endregion
        }


        /// <summary>
        /// 验证IP的有效性，如果是真实IP返回true
        /// </summary>
        /// <param name="IP"></param>
        /// <returns></returns>
        public static bool IsValidateIP(string IP)
        {
            bool bool_IsIP = false;
            if (!string.IsNullOrEmpty(IP))   //如果不为空进入验证，否则返回false
            {
                string[] ipArr = IP.Split('.');

                if (ipArr != null && ipArr.Length == 4)    //如果格式不对 返回false
                {
                    int int_cnt = 0;
                    foreach (string str_ip in ipArr)
                    {
                        int int_ip = 0;
                        try
                        {
                            int_ip = int.Parse(str_ip);

                        }
                        catch (Exception e)
                        {
                            //如果任何一段非数字类型 返回false
                            bool_IsIP = false;
                            break;
                        }

                        //如果是第一个IP段则最小值为1
                        int int_initIP = int_cnt == 0 ? 1 : 0;

                        if (int_ip < int_initIP || int_ip > 255)
                        {
                            //如果不在0-255之间返回false
                            bool_IsIP = false;
                            break;
                        }
                        int_cnt++;
                    }
                }
                else
                {
                    bool_IsIP = false;
                }
            }
            else
            {
                bool_IsIP = false;
            }
            return bool_IsIP;

        }

        public static string Get_HTTP_X_FORWARDED_FOR(HttpContext httpContext)
        {
            var ip = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            return ip;

        }

        public static string Get_HTTP_VIA(HttpContext httpContext)
        {
            return httpContext.Request.Headers["HTTP_VIA"].FirstOrDefault();
            //HttpContext.Current.Request.ServerVariables["HTTP_VIA"];

        }

        public static string Get_REMOTE_ADDR(HttpContext httpContext)
        {
            return httpContext.Connection.RemoteIpAddress.ToString();
            //HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

        }

        public static string Get_USERHOSTADDRESS(HttpContext httpContext)
        {
            return GetIPRealAddress(httpContext);

        }

        /// <summary>
        /// 是否使用代理 
        /// 跟据特殊判断是否使用代理访问
        /// </summary>
        /// <returns>true 是代理 false 不是代理</returns>
        public static bool IsProxy(HttpContext httpContext)
        {
            string str_t = null;
            string http_forworded = Get_HTTP_X_FORWARDED_FOR(httpContext);
            string http_via = Get_HTTP_VIA(httpContext);
            string remote_addr = Get_REMOTE_ADDR(httpContext);
            string userhostaddr = Get_USERHOSTADDRESS(httpContext);

            //四个属性全不为空，表示是模拟IP,是代理
            if(!string.IsNullOrEmpty(http_forworded) && !string.IsNullOrEmpty(http_via) && !string.IsNullOrEmpty(remote_addr) && !string.IsNullOrEmpty(userhostaddr)){
                return true;
            }

            //任何两个不同都是有误 ，可以判断为代理
            if (!string.IsNullOrEmpty(http_forworded) && http_forworded!= userhostaddr)
            {
                return true;
            }
            if (!string.IsNullOrEmpty(http_via) && http_via != userhostaddr)
            {
                return true;
            }
            if (!string.IsNullOrEmpty(remote_addr) && remote_addr != userhostaddr)
            {
                return true;
            }

            //任何一个不是真实IP，可以判断为代理
            if (!IsValidateIP(http_forworded))
            {
                return true;
            }
            if (!IsValidateIP(http_via))
            {
                return true;
            }
            if (!IsValidateIP(remote_addr))
            {
                return true;
            }
            if (!IsValidateIP(userhostaddr))
            {
                return true;
            }
            return false;
           
        }

        /// <summary>
        /// 从多个代理IP中拿到第一个IP
        /// </summary>
        /// <param name="IPs"></param>
        /// <returns></returns>
        private static string getFirstIPFromProxy(string IPs)
        {
            if (IPs.IndexOf(",") > -1)
            {
                return IPs.Split(',')[0];
            }
            else
            {
                return IPs;
            }
        }
        /// <summary>
        /// 获取真实IP地址
        /// 对果对方使用多层代理，则获取最后一层代理IP
        ///  HTTP_X_FORWARDED_FOR 可以伪造，不再信任HTTP_X_FORWARDED_FOR
        /// </summary>
        public static string GetIPRealAddress(HttpContext httpContext)
        {
  try
                {
                    //如果有X-Real-IP就取这个IP为客户端IP for Nginx

                    string x_Real_IP = httpContext.Request.Headers["HTTP_X_REAL_IP"].FirstOrDefault();
                    if (!string.IsNullOrEmpty(x_Real_IP))
                    {
                        return x_Real_IP;
                    }
                    else
                    {
                        // HTTP_X_FORWARDED_FOR 容易伪造，所以不再信任HTTP_X_FORWARDED_FOR这个头信息,直接获取REMOTE_ADDR
                        //if (string.IsNullOrEmpty(Request.ServerVariables["HTTP_X_FORWARDED_FOR"]))
                        string userIP = httpContext.Connection.RemoteIpAddress.ToString();
                    //else
                    //  userIP = getFirstIPFromProxy(Request.ServerVariables["HTTP_X_FORWARDED_FOR"]);
                    if (string.IsNullOrEmpty(userIP))
                            userIP = httpContext.Connection.LocalIpAddress.MapToIPv4().ToString();
                        return userIP;
                    }
                }
                catch
                {

                }
                return String.Empty;
                
        }
        /// <summary>
        /// 将IPv4格式的字符串转换为int型表示
        /// </summary>
        /// <param name="strIPAddress">IPv4格式的字符</param>
        /// <returns></returns>
        public static int IPToNumber(string strIPAddress)
        {
            //将目标IP地址字符串strIPAddress转换为数字
            string[] arrayIP = strIPAddress.Split('.');
            int sip1 = Int32.Parse(arrayIP[0]);
            int sip2 = Int32.Parse(arrayIP[1]);
            int sip3 = Int32.Parse(arrayIP[2]);
            int sip4 = Int32.Parse(arrayIP[3]);
            int tmpIpNumber;
            tmpIpNumber = sip1 * 256 * 256 * 256 + sip2 * 256 * 256 + sip3 * 256 + sip4;
            return tmpIpNumber;
        }


        /// <summary>
        /// 将int型表示的IP还原成正常IPv4格式。
        /// </summary>
        /// <param name="intIPAddress">int型表示的IP</param>
        /// <returns></returns>
        public static string NumberToIP(int intIPAddress)
        {
            int tempIPAddress;
            //将目标整形数字intIPAddress转换为IP地址字符串
            //-1062731518 192.168.1.2 
            //-1062731517 192.168.1.3 
            if (intIPAddress >= 0)
            {
                tempIPAddress = intIPAddress;
            }
            else
            {
                tempIPAddress = intIPAddress + 1;
            }
            int s1 = tempIPAddress / 256 / 256 / 256;
            int s21 = s1 * 256 * 256 * 256;
            int s2 = (tempIPAddress - s21) / 256 / 256;
            int s31 = s2 * 256 * 256 + s21;
            int s3 = (tempIPAddress - s31) / 256;
            int s4 = tempIPAddress - s3 * 256 - s31;
            if (intIPAddress < 0)
            {
                s1 = 255 + s1;
                s2 = 255 + s2;
                s3 = 255 + s3;
                s4 = 255 + s4;
            }
            string strIPAddress = s1.ToString() + "." + s2.ToString() + "." + s3.ToString() + "." + s4.ToString();
            return strIPAddress;
        }

        /// <summary>
        /// 优先获取IPUtils.IPRealAddress。如果非Web请求则返回服务器的IP GetLocalIP(1)
        /// </summary>
        /// <returns></returns>
        public static string GetUserHostAddress(HttpContext httpContext)
        {
            string IP = "";
            try
            {
                //IP = IPUtils.IPRealAddress;
                IP = string.Format("{0};", Get_HTTP_X_FORWARDED_FOR(httpContext));
                IP = string.Format("{0}{1};", IP, Get_HTTP_VIA(httpContext));
                IP = string.Format("{0}{1};", IP, Get_REMOTE_ADDR(httpContext));
                IP = string.Format("{0}{1};", IP, Get_USERHOSTADDRESS(httpContext));
            }
            catch
            {
                IP = GetLocalIP(1);
            }
            return IP;
        }
      
    }
}
